package com.sihan.framework.etm.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.framework.exception.BusinessException;
import com.framework.mybatis.Condition;
import com.framework.mybatis.service.impl.BaseServiceImpl;
import com.framework.util.WebUtils;
import com.sihan.framework.etm.entity.Permission;
import com.sihan.framework.etm.entity.RolePermission;
import com.sihan.framework.etm.mapper.PermissionMapper;
import com.sihan.framework.etm.mapper.RolePermissionMapper;
import com.sihan.framework.etm.service.PermissionService;
import com.sihan.framework.etm.vo.PermissionIdVO;
import com.sihan.framework.etm.vo.PermissionVO;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class PermissionServiceImpl extends BaseServiceImpl<Permission, String> implements
        PermissionService {

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Override
    public Set<String> selectPermissionsByRoles(Set<String> roles) {
        if (CollectionUtils.isNotEmpty(roles)) {
            return rolePermissionMapper.selectPermissionByRoles(roles);
        }
        return null;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<PermissionVO> permissionList() {
        List<Permission> permissions = permissionMapper
                .selectList(new Condition<>(new Permission(false)).eq("is_default", false));
        List<PermissionVO> result = new ArrayList<>(permissions.size());
        for (Permission permission : permissions) {
            PermissionVO permissionVO = new PermissionVO();
            BeanUtils.copyProperties(permission, permissionVO);
            permissionVO.setText(permission.getName());
            result.add(permissionVO);
        }
        return result;
    }

    @Override
    public List<PermissionVO> permissionTree() {
        // 列出所有权限信息，parentId是顶级权限0

        String parentId = "0";
        List<PermissionVO> all = permissionMapper.recursiveChildren(parentId);
//    List<PermissionVO> other = new ArrayList<>();
//    other.add(new PermissionVO(1L));
//    all.removeAll(other);
        return all;
    }

    @Override
    public List<PermissionVO> selectMenuPermissions(String username) {
        // 根据用户名称查询其所有的权限Id
        Set<String> selectedIds = rolePermissionMapper.selectPermissionIdsByUsername(username);
        // 查询所有的权限
        String parentId = "0";
        List<PermissionVO> treePermissions = permissionMapper.recursiveChildren(parentId);
        // 返回Menu权限树
        recursiveHandle(treePermissions, selectedIds);
        return treePermissions;
    }

    private void recursiveHandle(List<PermissionVO> permissions, Set<String> selectedIds) {
        Iterator<PermissionVO> iterator = permissions.iterator();
        while (iterator.hasNext()) {
            PermissionVO permissionVO = iterator.next();
//      if (selectedIds.contains(permissionVO.getId()) &&
//          StringUtils.equals(permissionVO.getResourceType(), "menu")) {
            if (selectedIds.contains(permissionVO.getId())) {
                if (StringUtils.equals(permissionVO.getResourceType(), "menu") || (StringUtils.equals(permissionVO.getResourceType(), "button") &&
                        permissionVO.getUrl() != null && !permissionVO.getUrl().equals(""))) {
                    List<PermissionVO> children = permissionVO.getChildren();
                    recursiveHandle(children, selectedIds);
                } else {
                    iterator.remove();
                }
            } else {
                iterator.remove();
            }
        }
    }

    @Override
    public void addPermission(Permission permission) {
        try {
            // 验证父类Id(parentId)是否存在或者为顶级权限
            String parentId = permission.getParentId();
            if (!StringUtils.isEmpty(parentId) && permissionMapper.selectById(permission.getParentId()) == null) {
                throw new BusinessException("分类权限不存在或者不是顶级权限");
            }
            // 插入权限
            permissionMapper.insert(permission);
        } catch (DuplicateKeyException e) {
            throw new BusinessException("权限标识已经存在");
        }
    }

    @Override
    @Transactional
    //@CacheEvict(cacheNames = "authorizationCache", allEntries = true)
    public void updatePermission(Permission permission) {
        try {
            String username = WebUtils.username();
            permission.setAvailable(true);
            // 判断是否修改了可用(available)字段，如果修改则需要其子权限的可用(available)字段
            Permission old = permissionMapper.selectById(permission.getId());
            if (!old.getAvailable().equals(permission.getAvailable())) {
                // 递归查询子权限Id
                List<PermissionIdVO> sons = permissionMapper.recursiveChildrenId(permission.getId());
                if (!CollectionUtils.isEmpty(sons)) {
                    List<String> permissionIds = new ArrayList<>();
                    resolveSonIds(sons, permissionIds);
                    permissionMapper
                            .updateAvailableByIds(permissionIds, permission.getAvailable(), new Date(), username);
                }
            }
            permissionMapper.updateById(permission);
        } catch (DuplicateKeyException e) {
            throw new BusinessException("权限标识已经存在");
        } catch (Exception e) {
            throw new BusinessException("系统错误，请稍后再试");
        }
    }

    @SuppressWarnings("rawtypes")
    @Override
    @Transactional
    //@CacheEvict(cacheNames = "authorizationCache", allEntries = true)
    public void deletePermission(List<String> permissionIds) {
        for (String permissionId : permissionIds) {
            // 查询是否有子权限
            Permission selectPermission = new Permission();
            selectPermission.setIsDelete(false);
            selectPermission.setParentId(permissionId);
            List<Permission> sons = permissionMapper.selectList(new Condition<>(selectPermission));
            if (!CollectionUtils.isEmpty(sons)) {
                throw new BusinessException("不能删除有子权限的权限");
            }
            // 删除权限
            Permission permission = new Permission();
            permission.setId(permissionId);
            permission.setIsDelete(true);
            permissionMapper.updateById(permission);
            // 删除角色权限信息
            RolePermission rolePermission = new RolePermission();
            rolePermission.setIsDelete(true);
            Condition condition = new Condition<>(rolePermission)
                    .eq("permission_id", permissionId)
                    .eq("is_delete", false);
            rolePermissionMapper.update(condition);
        }
    }

    private void resolveSonIds(List<PermissionIdVO> children, List<String> permissionIds) {
        if (CollectionUtils.isEmpty(children)) {
            return;
        }
        for (PermissionIdVO permissionIdVO : children) {
            permissionIds.add(permissionIdVO.getId());
            resolveSonIds(permissionIdVO.getChildren(), permissionIds);
        }
    }

    @Override
    public Set<String> rolePermissions(String roleId) {
        Set<String> selectedPermissionIds = rolePermissionMapper.selectPermissionIdsByRoleId(roleId);
        return selectedPermissionIds;
    }
}
